package com.ben.multiple.jsoup.rest;

import com.ben.multiple.jsoup.entity.Address;
import com.ben.multiple.jsoup.entity.Region;
import com.ben.multiple.jsoup.service.AddressServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping
@AllArgsConstructor
@Slf4j
public class RegionResource {
    private final AddressServiceImpl addressService;

    @GetMapping("/region/jsoup")
    public List<Region> jsoupRegion() {
        String url = "http://www.mca.gov.cn/article/sj/tjyb/qgsj/2019/201909291543.html";
        String provinceAndCityClass = "xl7026399";
        String areaClass = "xl7126399";
        Document document = this.selectOnline(url);
        List<Element> elementList = document.getAllElements().stream().filter(element ->
                element.className().equals(provinceAndCityClass) || element.className().equals(areaClass)).collect(Collectors.toList());
        log.info("elementList = {}", elementList);
        // 区域列表
        List<Region> regionList = new ArrayList<>();
        for (int i = 0; i < elementList.size(); i++) {
            regionList.add(new Region(elementList.get(i++).text(), elementList.get(i).text()));
        }
        log.info("regionList = {}", regionList);
        List<Region> regions = this.setParentIdForRegion(regionList);
        log.info("regions = {}", regions);
        return regions;
    }

    private Document selectOnline(String url) {
        Document document;
        try {
            document = Jsoup.connect(url).maxBodySize(Integer.MAX_VALUE).get();
        } catch (IOException e) {
            throw new RuntimeException("internet connect fail");
        }
        if (document == null) {
            throw new RuntimeException("internet connect fail");
        }
        return document;
    }

    /**
     * @param regionList 有序区域列表
     * @return 为市和区设置父 id
     */
    private List<Region> setParentIdForRegion(List<Region> regionList) {
        // 每次最外层循环中，已设置父 id 的个数，在 i++ 的基础上再加上此个数，减少最外层循环的次数
        int index;
        // 遍历整个列表，为定位省和直辖市
        for (int i = 0; i < regionList.size(); i += index + 1) {
            //每次循环开始时，个数重置为 0
            index = 0;
            Region region = regionList.get(i);
            if (region.getId().endsWith("0000")) {
                if (region.getName().contains("北京")
                        || region.getName().contains("天津")
                        || region.getName().contains("重庆")
                        || region.getName().contains("上海")) {
                    // 为直辖市下的区设置父 id
                    for (int j = i + 1; j < regionList.size(); j++) {
                        if (regionList.get(j).getId().endsWith("0000")) {
                            // 到下一个省或直辖市时，此直辖市下的所有区父 id 已全部处理，此循环结束
                            break;
                        }
                        regionList.get(j).setParentId(region.getId());
                        index++;
                    }
                } else {
                    // 为省下的 市设置父 id
                    for (int j = i + 1; j < regionList.size(); j++) {
                        Region child = regionList.get(j);
                        if (child.getId().startsWith(region.getId().substring(0, 2)) && child.getId().endsWith("00")) {
                            child.setParentId(region.getId());
                            index++;
                            // 为市下的 区设置父 id
                            for (int k = j + 1; k < regionList.size(); k++) {
                                if (regionList.get(k).getId().endsWith("00")) {
                                    // 到下一个市时，此市下的所有区父 id 已全部处理，此循环结束
                                    break;
                                }
                                regionList.get(k).setParentId(child.getId());
                                index++;
                            }
                        }
                    }
                }
            }
        }
        return regionList;
    }

    // address

    @GetMapping("/address/jsoup")
    public List<Address> jsoupAddress() {
        return addressService.jsoupAddress();
    }

}
